﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Media;
using GalaSoft.MvvmLight.Messaging;
using ProjectWizardManagement.Entity.Model;
using ProjectWizardManagementv1.ViewModels.Concrete;

namespace ProjectWizardManagementv1.WpfComponents.UserControls
{
    /// <summary>
    /// Interaction logic for CalendarControl.xaml
    /// </summary>
    public partial class AdvancedCalendar : UserControl
    {
        private static int NUM_OF_WEEKS = 6;
        private static int DAYS_OF_WEEK = 7;

        private static string[] MonthNames = {"", "January", "February", "March", "April", "May", "June", "July"
                                             ,"August", "September", "October", "November", "December"};

        private readonly DateBox[,] _dates;
        private int _currentYear;
        private readonly int _currentMonth;

        public AdvancedCalendar()
        {
            InitializeComponent();
            Messenger.Default.Register<CalendarEventViewModel>(this, AddCalendarEventToList);
            Messenger.Default.Register<RemoveCalendarDayMessage>(this, RemoveCalendarEventFromList);
            var firstDayOfCurrentMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            _currentMonth = firstDayOfCurrentMonth.Month;
            _currentYear = firstDayOfCurrentMonth.Year;
            var dayOfWeek = (int)firstDayOfCurrentMonth.DayOfWeek;
            var startDate = firstDayOfCurrentMonth.Subtract(TimeSpan.FromDays(dayOfWeek));

            _dates = new DateBox[NUM_OF_WEEKS,DAYS_OF_WEEK];

            for(int i = 1; i < NUM_OF_WEEKS + 1; i++)
            {
                for(int j = 0; j < DAYS_OF_WEEK; j++)
                {
                    _dates[i -1 , j] = new DateBox();
                    _dates[i - 1,j].SetValue(Grid.RowProperty, i);
                    _dates[i - 1,j].SetValue(Grid.ColumnProperty, j);
                    this.MonthTitle.Text = MonthNames[_currentMonth];
                    if(startDate.Day == DateTime.Now.Day && _currentMonth == startDate.Month)
                        _dates[i - 1, j].UnhighlightedColor = new SolidColorBrush(Color.FromArgb(255, 108, 255, 141));

                    if(startDate.Month == _currentMonth)
                        _dates[i - 1, j].DayNumber.Text = startDate.Day.ToString(CultureInfo.InvariantCulture);
                    else
                    {
                        _dates[i - 1, j].DayNumber.Text = 
                            string.Format("{0} {1}",MonthNames[startDate.Month], 
                            startDate.Day.ToString(CultureInfo.InvariantCulture));
                    }
                    this.CalendarGrid.Children.Add(_dates[i - 1, j]);
                    _dates[i - 1, j].AssignedDate = startDate;
                    startDate = startDate.AddDays(1);
                }
            }
        }

        private void AddCalendarEventToList(CalendarEventViewModel calendarEvent)
        {
            if (DateBox.CurrentEvents == null)
                DateBox.CurrentEvents = new ObservableCollection<DescriptionBox>();

            var description = new DescriptionBox
                                  {
                                      Title = calendarEvent.Name,
                                      DescriptionText = calendarEvent.Description,
                                      DayOfPosting = calendarEvent.ScheduledDate
                                  };

            DateBox.CurrentEvents.Add(description);
            RaisePropertiesForDates(description);
        }

        private void RemoveCalendarEventFromList(RemoveCalendarDayMessage calendarEvent)
        {
            var item = DateBox.CurrentEvents.FirstOrDefault(d => d.EventTitle.Text == calendarEvent.EventTitle &&
                                                                 d.EventDescription.Text == calendarEvent.Description &&
                                                                 d.DayOfPosting == calendarEvent.ScheduledDate);
            DateBox.CurrentEvents.Remove(item);
            RaisePropertiesForDates(item);
        }

        private void RaisePropertiesForDates(DescriptionBox box)
        {
            foreach (var date in _dates)
            {
                if (date.AssignedDate.Month == box.DayOfPosting.Month && date.AssignedDate.Day == box.DayOfPosting.Day)
                    date.RaisePropertyChanged();
            }
        }
    }

    public class RemoveCalendarDayMessage
    {
        public string EventTitle { get; set; }
        public string Description { get; set; }
        public DateTime ScheduledDate { get; set; }

        public RemoveCalendarDayMessage(CalendarEventViewModel model)
        {
            EventTitle = model.Name;
            Description = model.Description;
            ScheduledDate = model.ScheduledDate;
        }
    }
}
